#include "ChattingRoom.h"
#include "PrintInfo.h"
#include  <chrono>
#include  <random>

#include"UserManager.h"
#ifdef DEBUG
#include <iostream>
using namespace std;
#endif

ChattingRoomManager chat_room_manager;

extern UserManager user_manager;

string new_chat_id(const string& name){
    auto now=chrono::system_clock::now();
    auto time_now=chrono::system_clock::to_time_t(now);
    return to_string(time_now)+to_string(rand()%1000000);
}


string ChattingRoomManager::GetChatRoomFilePath(const string& chat_id) const{
   return CHAT_FILE_DIR+chat_id+".json";
}

void ChattingRoomManager::open_file(const string& file_path,ofstream& ofs) const{
    if(!fs::exists(CHAT_FILE_DIR)){
        fs::create_directories(CHAT_FILE_DIR);
    }
    ofs.open(file_path,ios::out);
}

void ChattingRoomManager::open_file(const string& file_path,ifstream& ifs) const{
    if(!fs::exists(CHAT_FILE_DIR)){
        fs::create_directories(CHAT_FILE_DIR);
    }
    ifs.open(file_path,ios::in);
}

void ChattingRoomManager::save_file(const string&path,const ChatRoom_ptr& chat_room) const{
    ofstream ofs;
    string temp_path = path + ".tmp"; // 创建临时文件路径
    open_file(temp_path, ofs); // 打开临时文件

    try {
        ofs << chat_room->serialize().dump(4) << endl; // 写入数据到临时文件
        ofs.close(); // 关闭临时文件
        fs::rename(temp_path, path); // 替换原文件
    } catch (json::exception& e) {
        PRINTF_LOG_AND_DEBUG(LOG_ERR, "save_file error:%s", e.what());
        ofs.close();
        fs::remove(temp_path); // 删除临时文件
    } catch (std::exception& e) {
        PRINTF_LOG_AND_DEBUG(LOG_ERR, "save_file unexpected error:%s", e.what());
        ofs.close();
        fs::remove(temp_path); // 删除临时文件
    }
}

shared_ptr<ChatRoom> ChattingRoomManager::LoadChatRoomContent(const string& chat_id){
    string file_path=GetChatRoomFilePath(chat_id);
    ifstream ifs;
    open_file(file_path,ifs);
    if(!ifs.is_open()){
        PRINTF_LOG_AND_DEBUG(errno,"打开文件失败:%s\n",file_path.c_str());
        return nullptr;
    }
    json j;

    ifs>>j;
    ifs.close();
    shared_ptr<ChatRoom> chat_room=make_shared<ChatRoom>();
    chat_room->unserialize(j);
    return chat_room;
}

void ChattingRoomManager::SaveChatRoomContent(){
    auto it=chat_rooms.begin();
    while(it!=chat_rooms.end()){
        save_file(GetChatRoomFilePath(it->first),it->second);
        it++;
    }
    chat_rooms.clear();
}


int ChattingRoomManager::QuickLoadChatContent(const string&chat_id,ChatRoom_ptr& chat_room){
    if(!chat_rooms.count(chat_id)||chat_rooms[chat_id]==nullptr){
        ChatRoom_ptr chat_room_content=LoadChatRoomContent(chat_id);
        if(chat_room_content==nullptr){
            return static_cast<int>(ChatRoomErr::NO_SUCH_CHAT_ROOM);
        }
        chat_rooms[chat_id]=move(chat_room_content);
    }
    chat_room=chat_rooms[chat_id];
    return static_cast<int>(ChatRoomErr::SUCCESS);
}
int ChattingRoomManager::QuickLoadChatContent(const string&chat_id,json& chat_content){
    if(!chat_rooms.count(chat_id)||chat_rooms[chat_id]==nullptr){
        ChatRoom_ptr chat_room_content=LoadChatRoomContent(chat_id);
        if(chat_room_content==nullptr){
            return static_cast<int>(ChatRoomErr::NO_SUCH_CHAT_ROOM);
        }
        chat_rooms[chat_id]=move(chat_room_content);
    }
    chat_content=chat_rooms[chat_id]->serialize();
    return static_cast<int>(ChatRoomErr::SUCCESS);
}

int  ChattingRoomManager::GetLatestChatMsg(const string& chat_id,const int& num_msg,deque<shared_ptr<Msg>>& chat_msg){
    if(!chat_rooms.count(chat_id)||chat_rooms[chat_id]==nullptr){
        chat_rooms[chat_id]=LoadChatRoomContent(chat_id);
        if(chat_rooms[chat_id]==nullptr){
            #ifdef DEBUG
            PRINTF_LOG_AND_DEBUG(LOG_INFO,"GetLatestChatMsg:聊天室不存在\n");
            #endif
            return static_cast<int>(ChatRoomErr::NO_SUCH_CHAT_ROOM);
        }
    }
    chat_msg.clear();
    chat_msg=chat_rooms[chat_id]->get_latest_chat_msg(num_msg);

    return static_cast<int>(ChatRoomErr::SUCCESS);
}
int ChattingRoomManager::GetLatestChatMsg(const string& chat_id,const int& num_msg,json& chat_msg){
    deque<shared_ptr<Msg>> chat_msg_deque;
    int result=GetLatestChatMsg(chat_id,num_msg,chat_msg_deque);
    try{
        chat_msg=json::array();
        for(const auto&msg:chat_msg_deque){ 
            chat_msg.push_back(msg->serializeMsg());
        }
    }catch(json::exception& e){
        PRINTF_LOG_AND_DEBUG(LOG_ERR, "GetLatestChatMsg error:%s", e.what());
        throw e;
    }
    return result;
}


int ChattingRoomManager::AddChatMsg(const string& chat_id,shared_ptr<Msg>msg){
    int result =0;
    if(chat_rooms.count(chat_id)==0||chat_rooms[chat_id]==nullptr){
       result=QuickLoadChatContent(chat_id,chat_rooms[chat_id]); 
       if(result!=0){
            #ifdef DEBUG
            PRINTF_LOG_AND_DEBUG(LOG_INFO,"AddChatMsg:聊天室不存在\n");
            #endif
            return result;
        }
    }

    chat_rooms[chat_id]->add_chat_msg(msg);    
    return result;
}

int ChattingRoomManager::CreateChatRoom(const int&owner_id,const string&chat_id,const string&chat_name){

    auto new_chat_room=make_shared<ChatRoom>(owner_id,chat_id,chat_name);
    new_chat_room->add_user(owner_id,user_manager.get_user_name(owner_id));

    #ifdef DEBUG
    cout<<"create_chat_room:"<<new_chat_room->serialize().dump(4)<<endl;
    #endif

    save_file(GetChatRoomFilePath(new_chat_room->get_chat_id()),new_chat_room);

    chat_rooms[new_chat_room->get_chat_id()]=move(new_chat_room);
    return 0;
}

string ChattingRoomManager::CreateChatRoom(const int&owner_id,const string&chat_name){
    string newchatid=new_chat_id(chat_name);
    if(CreateChatRoom(owner_id,newchatid,chat_name)==0){
        return newchatid;
    }else{
        return "";//创建失败
    }
}


// bool ChattingRoomManager::DeleteChatRoom(const string& chat_id,const int&request_user_id,string &info){
//     if(fs::exists(GetChatRoomFilePath(chat_id))){
//         ChatRoom_ptr chat_room;
//         QuickLoadChatContent(chat_id,chat_room);
//         if(chat_room->get_owner_id()!=request_user_id){
//             info="不是聊天室所有者";
//             return false;
//         }
//         else{
//             chat_rooms.erase(chat_id);
//             info="删除成功";
//             return true;
//         }
//     }
//     else{
//         info="聊天室不存在";
//         return false;
//     }
// }

int ChattingRoomManager::DeleteChatRoom(const string& chat_id,const int&request_user_id){
    ChatRoom_ptr chat_room;
    if(QuickLoadChatContent(chat_id,chat_room)!=0){
        #ifdef DEBUG
        PRINTF_LOG_AND_DEBUG(LOG_INFO,"DeleteChatRoom:聊天室不存在\n");
        #endif
        return static_cast<int>(ChatRoomErr::NO_SUCH_CHAT_ROOM);
    }
    if(chat_room->get_owner_id()!=request_user_id){
        #ifdef DEBUG
        PRINTF_LOG_AND_DEBUG(LOG_INFO,"DeleteChatRoom:不是聊天室所有者\n");
        #endif
        return static_cast<int>(ChatRoomErr::NOT_OWNER);
    }
    chat_rooms.erase(chat_id);

    fs::remove(GetChatRoomFilePath(chat_id));

    return static_cast<int>(ChatRoomErr::SUCCESS);
}



// void ChattingRoomManager::JoinChatRoom(const string& chat_id,const int& user_id,const string &user_name,string&info){
//     ChatRoom_ptr chat_room;
//     QuickLoadChatContent(chat_id,chat_room);
//     if(chat_room->is_user_in_room(user_id)){
//         info="已经在聊天室中";
//         return ;
//     }


//     chat_room->add_user(user_id,user_name);
//     info="加入聊天室成功";
//     return ;
// }

int ChattingRoomManager::JoinChatRoom(const string& chat_id,const int& user_id,const string &user_name){
    ChatRoom_ptr chat_room;
    
    if(QuickLoadChatContent(chat_id,chat_room)==ChatRoomErr::NO_SUCH_CHAT_ROOM){
        #ifdef DEBUG
        PRINTF_LOG_AND_DEBUG(LOG_INFO,"JoinChatRoom:聊天室不存在\n");
        #endif
        return static_cast<int>(ChatRoomErr::NO_SUCH_CHAT_ROOM);
    }

    if(chat_room->is_user_in_room(user_id)){
        #ifdef DEBUG
        PRINTF_LOG_AND_DEBUG(LOG_INFO,"JoinChatRoom:用户已经在聊天室中\n");
        #endif
        return  static_cast<int>(ChatRoomErr::ALLREADY_IN_ROOM);
    }
    chat_room->add_user(user_id,user_name);

    #ifdef DEBUG
    this->save_file(GetChatRoomFilePath(chat_id),chat_room);
    #endif


    return static_cast<int>(ChatRoomErr::SUCCESS);
}

int ChattingRoomManager::ExitChatRoom(const string& chat_id,const int& user_id){
    ChatRoom_ptr chat_room;
    if(QuickLoadChatContent(chat_id,chat_room)!=0){
        #ifdef DEBUG
        PRINTF_LOG_AND_DEBUG(LOG_INFO,"ExitChatRoom:聊天室不存在\n");
        #endif
        return static_cast<int>(ChatRoomErr::NO_SUCH_CHAT_ROOM);
    }

    if(chat_room->is_user_in_room(user_id)){
        chat_room->remove_user(user_id);
        #ifdef DEBUG
        this->save_file(GetChatRoomFilePath(chat_id),chat_room);
        #endif

        return static_cast<int>(ChatRoomErr::SUCCESS);
    }
    else{
        #ifdef DEBUG
        PRINTF_LOG_AND_DEBUG(LOG_INFO,"ExitChatRoom:用户不在聊天室中\n");
        #endif
        return static_cast<int>(ChatRoomErr::NO_SUCH_USER);
    }

}

bool ChattingRoomManager::is_chat_room_exist(const string& chat_id) const{
    return fs::exists(GetChatRoomFilePath(chat_id));
}

bool ChattingRoomManager::is_owner(const string& chat_id,const int& user_id){
    ChatRoom_ptr chat_room;
    QuickLoadChatContent(chat_id,chat_room);
    return chat_room->is_owner(user_id);
}

void ChattingRoomManager::clear_chat_room_cache_func(int clear_frequency) {
    while (this->is_clear_chatroom_cache_on) {
        std::this_thread::sleep_for(std::chrono::seconds(clear_frequency));
        try {
            {
                std::lock_guard<std::mutex> lock(chat_room_mutex);
                SaveChatRoomContent();
                
                #ifdef DEBUG
                PRINTF_LOG_AND_DEBUG(LOG_INFO, "clear_chat_room_cache_func: 清理聊天室缓存\n");
                #endif
            }
            // 等待指定的时间间隔
        } catch (const std::exception& e) {
            #ifdef DEBUG
            PRINTF_LOG_AND_DEBUG(LOG_ERR, "clear_chat_room_cache_func: 异常 %s\n", e.what());
            #endif
            syslog(LOG_ERR, "clear_chat_room_cache_func: 异常 %s\n", e.what());
        }
    }
}
